package com.cskaoyan.operator;


/*


  位运算符: 针对变量的二进制位来进行运算
  移位运算：

  a.左移运算符 <<： 空位补0，被移除的高位丢弃。
                   左移一位相当于给操作数 * 2(左移之后的结果仍然在，相应数据类型的表示范围之内)


  b.带符号的右移：被移位的二进制最高位是0，右移后，空缺位补0；最高位是1，最高位补1。
                  右移一位，相当于整数除法，除以2



 c. 无符号右移：移位的动作和带符号数一模一样的，右移之后，高位直接填充0,
              无符号右移，同常用来处理正整数，对正整数而言，无符号右移一位相当于除以2

   &： 只针对二进制的一位 0或者1，只有两个二进制都为1的时候结果为1，其余全为0
      0 & 1 = 0     0 & 0 = 0    1 & 0 = 0  1 & 1 = 1

 |:  只有两位全为0的时候结果才为0
     0 | 1 = 1    0 | 0 = 0     1 | 0 = 1  1 | 1 = 1

  ^: 相同为0，不同为1
    0 ^ 1 = 1    0 ^ 0 = 0      1 ^ 0 = 1   1 ^ 1 = 0
     性质：
    1. 一个数和它自己异或运算的结果：a ^ a = 0
    2. 一个数和0做异或运算 a ^ 0 = a

  ~: 按位取反(包括符号位)：把二进制的每一位都取反
 */
public class Bit {

    public static void main(String[] args) {
        // 左移运算 <<
        //       00000000 00000000 00000000 00000001
        //左移   0000000 00000000 00000000 000000010
        int a = 1;
        System.out.println(a << 1);

        int b = -3;

        // 带符号的右移
        // 原码：10000000 00000000 00000000 000000011
        // 补码: 11111111 11111111 11111111 11111101
        // 右移  11111111 11111111 11111111 11111110
        // 原码  10000000 00000000 00000000 00000010
        System.out.println( b >> 1); // -2

        // 无符号右移(我们在实际开发中，只会针对正整数使用)
        // 补码: 11111111 11111111 11111111 11111101
        // 右移: 011111111 11111111 11111111 1111110
        // 原码：011111111 11111111 11111111 1111110
        System.out.println(b >>> 1);

        int c = 1;
        int d = 3;

        // & 运算
        // c: 00000000 00000000 00000000 00000001
        // d: 00000000 00000000 00000000 00000011
        //    00000000 00000000 00000000 00000001
        System.out.println(c & d);

        // | 运算
        // c: 00000000 00000000 00000000 00000001
        // d: 00000000 00000000 00000000 00000011
        //    00000000 00000000 00000000 00000011
        System.out.println(c | d);

        // ^ 运算
        // c: 00000000 00000000 00000000 00000001
        // d: 00000000 00000000 00000000 00000011
        //    00000000 00000000 00000000 00000010
        System.out.println(c ^ d);

        // 按位取反运算
        int e = 6;
        //补码：  00000000 00000000 00000000 00000110
        //取反:   11111111 11111111 11111111 11111001
        //原码:   10000000 00000000 00000000 00000111
        System.out.println(~e); // -7

        // 异或运算的性质
        // 一个数和它自己异或运算的结果：a ^ a = 0
        System.out.println(e ^ e);

        //一个数和0做异或运算 a ^ 0 = a
        System.out.println(e ^ 0);


    }
}
